package img

import (
	"common/mildware"
	"common/models"
	"common/ofile"
	"common/snowflake"
	"errors"
	"github.com/gin-gonic/gin"
	"go.uber.org/zap"
	"math/rand"
	"os"
	"path"
	"strconv"
	"strings"
	"time"
	"video/pkg/dao/redis"
)

// UpImg 上传图片
// @Summary 上传图片
// @Description 上传图片
// @Tags 图片
// @Accept multipart/form-data
// @Param img formData file true "上传value=“img”"
// @Produce application/json
// @Param Authorization header string true "Bearer 用户令牌"
// @Success 200 {object} docModel.DocResp
// @Router /img/up [post]
func (h IHandler) UpImg(c *gin.Context) {
	var (
		fileName, size, src, format, uid, authorId string
		err                                        error
	)
	resp := new(models.RespData)
	imgResp := new(models.UpImgResp)
	//获得ID
	authorId, uid, _, err = mildware.GetCyrrentUserID(c)
	if err != nil {
		resp.SendCode(c, models.CodeInvalidToken)
		return
	}
	file, err := c.FormFile("img")
	if err != nil {
		zap.L().Info("Img:UpImg video up err")
		resp.SendCode(c, models.CodeVideoUpErr)
		return
	}
	var upLoadDir string
	//定义文件保存地址
	upLoadDir = ofile.MkdirUserInfo(uid, ofile.Img)
	_, err = os.Stat(upLoadDir)
	if os.IsNotExist(err) {
		os.Mkdir(upLoadDir, os.ModePerm)
	}
	fileName = file.Filename
	format = strings.Split(fileName, ".")[1]
	//fileName 脱敏
	fileId := strconv.FormatInt(time.Now().Unix(), 10) + strconv.Itoa(rand.Intn(999999-100000)+10000)
	newFileName := fileId + path.Ext(file.Filename)
	src = upLoadDir + newFileName
	err = c.SaveUploadedFile(file, src)
	if err != nil {
		zap.L().Error("Img : c.SaveUploadedFile error", zap.Error(err))
		resp.SendCode(c, models.CodeFileErr)
		return
	}
	//存储到数据库
	imgInfo := &models.ImageInfo{
		ImageId:  strconv.FormatInt(snowflake.GenID(), 10),
		AuthorId: authorId,
		Src:      src,
		Size:     size,
		Format:   format,
	}
	//mysql
	if err = h.M.ImgInfoAdd(imgInfo); err != nil {
		zap.L().Error("Img :h.M.ImgInfoAdd error", zap.Error(err))
		resp.SendServerBusy(c)
		return
	}
	//将链接放到redis
	if err = h.R.SetString(redis.ImgPath+imgInfo.ImageId, imgInfo.Src, 5*time.Minute); err != nil {
		zap.L().Error("Img :h.R.SetString error", zap.Error(err))
		resp.SendServerBusy(c)
		return
	}
	imgResp.ImgId = imgInfo.ImageId
	imgResp.Src = imgInfo.Src
	resp.Data = imgResp
	resp.SendSuccess(c)
}

// DownImg 下载图片文件
// @Summary 下载图片文件
// @Description 下载图片文件
// @Tags 图片
// @Param img_id query string true "?img_id=xxx"
// @Success 200 {object}  interface{}
// @Router /img/down [get]
func (h IHandler) DownImg(c *gin.Context) {
	resp := new(models.RespData)
	imgId := c.Query("img_id")
	//直接redis读
	result, err := h.R.GetString(redis.ImgPath + imgId)
	if err != nil {
		if errors.Is(err, redis.NoKey) {
			//获得地址
			exist, id, err := h.M.ImgInfoCheckByUid(imgId)
			if err != nil {
				zap.L().Error("Img : h.M.ImgInfoCheckByUid error", zap.Error(err))
				resp.SendServerBusy(c)
				return
			}
			if !exist {
				resp.SendCode(c, models.CodeNotFindFile)
				return
			}
			idStr := strconv.Itoa(id)
			imgInfo, err := h.M.ImgInfoQueryById(idStr)
			if err != nil {
				zap.L().Error("Img : h.M.ImgInfoQueryByUid error", zap.Error(err))
				resp.SendServerBusy(c)
				return
			}
			//将链接放到redis
			if err = h.R.SetString(redis.ImgPath+imgInfo.ImageId, imgInfo.Src, 5*time.Minute); err != nil {
				zap.L().Error("Img :h.R.SetString error", zap.Error(err))
				resp.SendServerBusy(c)
				return
			}
			//响应一个文件
			c.File(imgInfo.Src)
			return
		}
		zap.L().Error("Img : h.R.GetString error", zap.Error(err))
	}
	if result != "" {
		c.File(result)
		return
	}
}
